package main

import "fmt"

type TreeNode struct {
	Left *TreeNode
	Right *TreeNode
	Val int
}

//1. 使用函数式编程，遍历树. 中序遍历
func (node *TreeNode) TraverseFunc(f func(*TreeNode)) {
	if node == nil {
		return
	}

	node.Left.TraverseFunc(f)
	f(node)
	node.Right.TraverseFunc(f)
}


// 2. 使用 channel进行 数的遍历
// 和之前的例子一样， TraverseWithChannel() 相当于是 createWorker 的作用。创建一个 channel 并返回
func (node *TreeNode) TraverseWithChannel() chan *TreeNode {
	out := make(chan *TreeNode)
	// 开启goroutine，写入node节点
	go func() {
		node.TraverseFunc(func(node *TreeNode) {
			out <- node
		})
		// 关闭
		close(out)
	}()

	return out
}



func main() {
	// 0. 先进行创建 树
	root := TreeNode{nil, nil, 1}
	root.Left = &TreeNode{nil, nil, 5}
	root.Right = &TreeNode{Val: 4}
	root.Right.Left = new(TreeNode)
	root.Left.Right = &TreeNode{nil, nil, 3}


	// 1. 调用 函数式遍历，f 匿名函数，统计节点个数
	count := 0
	root.TraverseFunc(func(node *TreeNode) {
		count++
		fmt.Println(node.Val)
	})
	fmt.Println("Tree has Node count: ", count)


	// 2. 通过channel
	c:= root.TraverseWithChannel()
	// 通过range 就可以遍历节点了, 统计元素值最大的
	maxNodeVal := 0
	for node := range c {
		if node.Val > maxNodeVal {
			maxNodeVal = node.Val
		}
	}
	fmt.Println("Max Node Value: ", maxNodeVal)
}
